/**
* Created by xinxinran on 15/9/16.
*/
const mongoose = require('mongoose'),
    Schema = mongoose.Schema,
    commonUtil = require('./commonUtil'),
    Q = require('q'),
    daoCache = {},
    mongoHost = require('./config/mongo.json')['host.' + ((process.env.NODE_ENV || 'dev').startsWith('dev') ? 'dev' : 'prod')];

mongoose.model('interface', new Schema({
    interfaceId : {type : String, default : ''},
    order : {type : Number, default : 0},
    depth : {type : Number, default : 0},
    code : {type : String, default : ''},
    name : {type : String, default : ''},
    parentId : {type : String, default : ''},
    createDate : Date
}, {collection : 'interface'}));

mongoose.model('interfaceDetail', new Schema({
    interfaceId : {type : String, default : ''},
    interfaceCode : {type : String, default : ''},
    interfaceName : {type : String, default : ''},
    author : {type : String , default : ''},
    name : {type : String, default : ''},
    url : {type : String, default : ''},
    ifType : {type : String, default : 'if'},
    params : [{type : String}],
    paramType : {type : Number, default : 0},
    desc : {type : String, default : ''},
    resultDemo : {type : String, default : ''},
    resultPage : {type : String, default : ''},
    attrInfos : [{type : String}],
    createDate : Date
}, {collection : 'interfaceDetail'}));

mongoose.model('userAuth', new Schema({
    userName : {type : String, default : ''},
    pass : {type : String, default : ''},
    name : {type : String, default : ''},
    auth : [{type : String}],
    isAdmin : {type : Boolean, default : false}
}, {collection : 'userAuth'}));

mongoose.model('appInfos', new Schema({
    name : {type : String, default : ''},
    pathName : {type : String, default : ''},
    enabled : {type : Boolean, default : true},
    sortNum : {type : Number, default : 999}
}, {collection : 'appInfos'}));

const Dao = function (dbName) {
    const conn = mongoose.createConnection(`mongodb://${mongoHost}/${dbName}`);

    this.ifModel = conn.model('interface');
    this.ifDetailModel = conn.model('interfaceDetail');
};

commonUtil.extendObj(Dao.prototype, {
    getInterfaces : function(depth){
        const deferred = Q.defer();
        this.ifModel.find({depth : depth}, '', {sort: {order: 1, createDate : 1}}, deferred.makeNodeResolver());
        return deferred.promise.catch(e => {console.log(e)});
    },
    getAllDetail : function(){
        const deferred = Q.defer();
        this.ifDetailModel.find({}, deferred.makeNodeResolver());
        return deferred.promise;
    },
    updateModule : function(saveObj){
        const deferred = Q.defer();
        this.ifModel.findOneAndUpdate({interfaceId : saveObj.interfaceId}, saveObj, deferred.makeNodeResolver());
        return deferred.promise;
    },
    saveModule : function(saveObj){
        const deferred = Q.defer();
        this.ifModel.create(saveObj, deferred.makeNodeResolver());
        return deferred.promise;
    },
    updateInterface : function(saveObj){
        const deferred = Q.defer();
        this.ifDetailModel.findOneAndUpdate({interfaceId : saveObj.interfaceId}, saveObj, deferred.makeNodeResolver());
        return deferred.promise;
    },
    saveInterface : function(saveObj){
        const deferred = Q.defer();
        this.ifDetailModel.create(saveObj, deferred.makeNodeResolver());
        return deferred.promise;
    },
    getModuleById : function(id){
        const deferred = Q.defer();
        this.ifModel.findOne({interfaceId : id}, deferred.makeNodeResolver());
        return deferred.promise;
    },
    getInterfaceById : function(id){
        const deferred = Q.defer();
        this.ifDetailModel.findOne({interfaceId : id}, deferred.makeNodeResolver());
        return deferred.promise;
    },
    getInterfaceByUrl : function(url){
        const deferred = Q.defer();
        this.ifDetailModel.findOne({url}, deferred.makeNodeResolver());
        return deferred.promise;
    },
    getJspDataByUrl : function(url){
        const deferred = Q.defer();
        this.ifDetailModel.findOne({url, ifType : 'jsp'}, deferred.makeNodeResolver());
        return deferred.promise;
    },

    getAllJspData : function(){
        const deferred = Q.defer();
        this.ifDetailModel.find({ifType : 'jsp'}, deferred.makeNodeResolver());
        return deferred.promise;
    },
    removeInterface : function(id){
        const deferred = Q.defer();
        //noinspection JSCheckFunctionSignatures
        this.ifModel.remove({interfaceId : id}, deferred.makeNodeResolver());
        return deferred.promise;
    },
    removeInterfaceDetail : function(ifId){
        const deferred = Q.defer();
        //noinspection JSCheckFunctionSignatures
        this.ifDetailModel.remove({interfaceId : ifId}, deferred.makeNodeResolver());
        return deferred.promise;
    },
    getInterfacesByModuleId : function(mId){
        const deferred = Q.defer();
        this.ifModel.find({parentId : mId}, deferred.makeNodeResolver());
        return deferred.promise;
    }
});

const AdminDao = function (){
    const conn = mongoose.createConnection(`mongodb://${mongoHost}/minidoc-interfaceAdmin`);

    this.userModel = conn.model('userAuth');
    this.appModel = conn.model('appInfos');
};

commonUtil.extendObj(AdminDao.prototype, {
    addUser : function(saveObj){
        const deferred = Q.defer();
        this.userModel.create(saveObj, deferred.makeNodeResolver());
        return deferred.promise;
    },
    getAllApps : function(includeDisabled){
        let deferred = Q.defer(), queryObj = includeDisabled ? {} : {enabled : true};
        this.appModel.find(queryObj, deferred.makeNodeResolver());
        return deferred.promise;
    },
    getAllUsers : function(){
        let deferred = Q.defer();
        this.userModel.find({}, deferred.makeNodeResolver());
        return deferred.promise;
    }
});

module.exports = {
    getDao : function(appName){
        let thisDao;
        appName = appName || 'appInterface';
        if(!(thisDao = daoCache[appName])){
            thisDao = daoCache[appName] = appName === 'minidoc-interfaceAdmin' ? new AdminDao() :  new Dao(appName);
        }
        return thisDao;
    }
};
